//package com.zzyy.study.utils;
//
//import lombok.Data;
//import lombok.extern.slf4j.Slf4j;
//
//import java.util.concurrent.*;
//import java.util.concurrent.atomic.AtomicInteger;
//
//@Slf4j
//public class PerformanceRunnerUtil2 {
//    //1 静态内部类，封装返回压测结果集PerformanceRunnerResult
//    @Data
//    public  static class  PerformanceRunnerResult2 {
//        //请求总数
//        private int requests;
//        //并发量
//        private int concurrency;
//        // 成功请求数
//        private int successRequests;
//        // 失败请求数
//        private int failRequests;
//        // 请求总耗时(ms)
//        private int timeTakenForTests;
//        // 每秒请求数（吞吐量）
//        private float requestsPerSecond;
//        // 每个请求平均耗时(ms)
//        private float timePerRequest;
//        // 最快的请求耗时(ms)
//        private float fastestCostTime;
//        // 最慢的请求耗时(ms)
//        private float slowestCostTime;
//    }
//    //2.定义通用的压测方法
//
//    public static <T> PerformanceRunnerResult2 performanceRun2(int requests,int concurrency,Runnable runnable)
//        throws InterruptedException
//    {
//        log.info("PerformanceRunnerUtil压测开始......");
//        //静态内部类，压测返回结果集
//        PerformanceRunnerResult2 retValue = new PerformanceRunnerResult2();
//
//        //2.1创建线程池并将所有核心线程池准备好core=max,直接性能拉满
//        //为了通用直接使用JDK自带的JUC线程池
//        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
//                concurrency,
//                concurrency,
//                0L,
//                TimeUnit.MILLISECONDS,
//                new LinkedBlockingQueue<>());
//        //2.2 启动所有核心线程
//        threadPool.prestartAllCoreThreads();
//        //2.3 创建一个CountDownLatch,用于阻塞当前线程池，待所有请求处理完毕后，让当前线程继续向下走
//        CountDownLatch countDownLatch = new CountDownLatch(requests);
//        //2.4 成功请求数-最快耗时-最慢耗时
//        AtomicInteger successRequests = new AtomicInteger();
//        AtomicInteger fastestCostTime = new AtomicInteger(Integer.MAX_VALUE);
//        AtomicInteger slowestCostTime = new AtomicInteger(Integer.MIN_VALUE);
//
//        long startTime = System.currentTimeMillis();
//        try {
//            for (int i = 0; i < requests; i++) {
//                threadPool.execute(()->{
//                    try {
//                        //某个顾客做到窗口前的时间
//                        long requestStartTime = System.currentTimeMillis();
//                        //执行被压测的方法
//                        runnable.run();
//                        //业务逻辑压测方法执行耗时
//                        int costTime = (int) (System.currentTimeMillis() - requestStartTime);
//                        //请求最快耗时
//                        setFastestCostTime(fastestCostTime,costTime);
//                        //请求最慢耗时
//                        setSlowestTimeCostTIme(slowestCostTime,costTime);
//                        //成功请求数+1
//                        successRequests.incrementAndGet();//++i
//                    } catch (Exception e) {
//                        log.error(e.getMessage());
//                    } finally {
//                        countDownLatch.countDown();
//                    }
//                });
//            }
//            //阻塞当前线程，等到压测结束后，该方法会被唤醒，线程继续向下走
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            //关闭线程池
//            threadPool.shutdown();
//        }
//        long endTime = System.currentTimeMillis();
//        System.out.println("-------costTime: "+(endTime-startTime)+"毫秒");
//
//        //组装最后的结果并返回
//        retValue.setRequests(requests);
//        retValue.setConcurrency(concurrency);
//        retValue.setSuccessRequests(successRequests.get());
//        retValue.setFailRequests(requests-retValue.getSuccessRequests());
//        retValue.setTimeTakenForTests((int)(endTime-startTime));
//        retValue.setRequestsPerSecond((float) requests * 1000f /(float)(retValue.getTimeTakenForTests()));
//        retValue.setTimePerRequest((float) retValue.getTimePerRequest()/(float) requests);
//        retValue.setFastestCostTime(fastestCostTime.get());
//        retValue.setSlowestCostTime(slowestCostTime.get());
//
//        return retValue;
//
//    }
//
//    private static void setFastestCostTime(AtomicInteger fastestCostTime,int costTime){
//        while (true){
//            int fsCostTime = fastestCostTime.get();
//            if (fsCostTime<costTime){
//                break;
//            }
//            if (fastestCostTime.compareAndSet(fsCostTime,costTime)){
//                break;
//            }
//        }
//    }
//    private static void setSlowestTimeCostTIme(AtomicInteger slowestCostTime,int costTime){
//        while (true){
//            int slCostTime = slowestCostTime.get();
//            if (slCostTime>costTime){
//                break;
//            }
//            if (slowestCostTime.compareAndSet(slCostTime,costTime)){
//                break;
//            }
//        }
//    }
//
//}
